package fetcher

import (
	"bufio"
	"dxmtools"
	"fmt"
	"io"
	"log"
	"net/http"
	"os"
	"path/filepath"
	"regexp"
	"strings"
)

var suffixTypeReg = regexp.MustCompile(`[a-zA-Z0-9]+/([a-zA-Z0-9]+)`)
func ExtractSuffix(ts string) string{
	ms := suffixTypeReg.FindAllStringSubmatch(ts,-1)
	if len(ms) > 0{
		return ms[0][1]
	}
	return "err"
}

func makeRequest(src string,method string,headers map[string]string) (*http.Request,error){
	request,err := http.NewRequest(method,src,nil)
	if err != nil {
		return request,err
	}
	if headers != nil {
		for k,v := range headers{
			request.Header.Add(strings.TrimSpace(k),strings.TrimSpace(v))
		}
	}
	return request,err
}
func downFile(src string,name string ,outdir string,method string,headers map[string]string) ImgResult{
	result := ImgResult{}
	result.Src = src
	result.Name = name
	client := &http.Client{}
	request,err := makeRequest(src,method,headers)
	if err != nil {
		result.StatusCode = -110
		log.Println(err)
		return result
	}
	resp,err := client.Do(request)
	if err != nil {
		result.StatusCode = -100
		log.Println(err)
		return result
	}
	defer resp.Body.Close()
	result.StatusCode =resp.StatusCode

	if result.StatusCode == 200 {
		reader := bufio.NewReaderSize(resp.Body,32*1024)
		newFilePath := filepath.FromSlash(outdir+"/")
		ext := ExtractSuffix(resp.Header.Get("Content-Type"))
		filePaths := strings.Split(name,"_")
		fileName := fmt.Sprintf("%s.%s",filePaths[0],ext)
		for index,filePath := range filePaths{
			if index > 0 {
				filePaths[index] = dxmtools.CompressStr(filePath)
			}
		}
		if len(filePaths) > 1{
			newFilePath = filepath.FromSlash(outdir+"/"+strings.Join(filePaths[1:],"/"))
			subExists,_:=dxmtools.PathExists(newFilePath)
			if !subExists{
				os.MkdirAll(newFilePath,os.ModePerm)
			}
		}

		file,err := os.Create(filepath.FromSlash(newFilePath+"/"+fileName))
		writer := bufio.NewWriterSize(file,32*1024)
		if err != nil {
			log.Println(err)
			return  result
		}

		size,_ := io.Copy(writer,reader)
		result.Ext =ext
		result.Size = size

		defer writer.Flush()
	}

	return result
}

func StartInTask(in chan ImgInfo,outdir string,logFile io.Writer,out chan int,method string,headers map[string]string)   {
	go func() {
		for{
			imgInfo := <- in
			//TODO down img from network
			result := downFile(imgInfo.Src,imgInfo.NameId,outdir,method,headers)
			resultStr := fmt.Sprintf("%s %s %d %d %s\n",result.Src,result.Name,result.StatusCode,result.Size,result.Ext)
			_,err:=io.WriteString(logFile,resultStr)
			if err != nil {
				log.Println(err)
			}
			out <- 1
		}
	}()
}
